package io.renren.controller;

import io.renren.annotation.Login;
import io.renren.annotation.LoginUser;
import io.renren.cloud.OSSFactory;
import io.renren.common.exception.RRException;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.R;
import io.renren.common.validator.Assert;
import io.renren.common.validator.ValidatorUtils;
import io.renren.entity.MemberEntity;
import io.renren.entity.SysOssEntity;
import io.renren.form.AuthForm;
import io.renren.form.PayForm;
import io.renren.form.UserInfoForm;
import io.renren.service.MemberService;
import io.renren.service.SysOssService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.UUID;

import net.coobird.thumbnailator.Thumbnails;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.mapper.EntityWrapper;

import springfox.documentation.annotations.ApiIgnore;

/**
 * 会员接口
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2017-03-23 15:31
 */
@RestController
@RequestMapping("/api/member")
@Api(tags = "会员接口")
public class ApiMemberController extends AbstractController {

	@Autowired
	private MemberService memberService;

	@Autowired
	private SysOssService sysOssService;

	@Login
	@PostMapping("info")
	@ApiOperation("获取会员信息")
	public R info(@ApiIgnore @LoginUser MemberEntity member) {
		member.setSumBalance(DecimalUtils.add(member.getBalance(), member.getBlockedBalance()));
		// 混淆支付密码
		if (StringUtils.isNotBlank(member.getPayword())) {
			member.setPayword("set");
		}
		return R.ok().put("member", member);
	}

	@Login
	@PostMapping("update")
	@ApiOperation("修改会员信息")
	public R update(@ApiIgnore @LoginUser MemberEntity member, @RequestBody UserInfoForm form) {

		if (StringUtils.isNotBlank(form.getNickname())) { // 设置昵称

			member.setNickname(form.getNickname());

		} else if (StringUtils.isNotBlank(form.getPasswordOld())) {// 修改登录密码

			Assert.hasText(form.getPassword1(), "新登录密码不能为空");
			Assert.hasText(form.getPassword2(), "新登录密码不能为空");
			Assert.isTrue(form.getPassword1().length() >= 6 && form.getPassword2().length() >= 6, "新登录密码长度过短");
			if (!form.getPassword1().equals(form.getPassword2())) {
				throw new RRException("新登录密码两次输入不一致");
			}

			String oldPwd = member.getPassword();
			String odlPwd1 = DigestUtils.sha256Hex(form.getPasswordOld() + member.getSalt());
			Assert.isTrue(oldPwd.equals(odlPwd1), "旧登录密码错误");

			// 设置新密码
			member.setPassword(DigestUtils.sha256Hex(form.getPassword1() + member.getSalt()));

		} else if (StringUtils.isNotBlank(form.getPaywordOld()) || StringUtils.isNotBlank(form.getPayword1())) {// 修改支付密码

			// 验证是否已设置了支付密码
			if (StringUtils.isNotBlank(member.getPayword())) {
				Assert.hasText(form.getPaywordOld(), "旧支付密码不能为空");
				String oldPwd = member.getPayword();
				String odlPwd1 = DigestUtils.sha256Hex(form.getPaywordOld() + member.getSalt());
				Assert.isTrue(oldPwd.equals(odlPwd1), "旧支付密码错误");
			}

			Assert.hasText(form.getPayword1(), "新支付密码不能为空");
			Assert.hasText(form.getPayword2(), "新支付密码不能为空");
			Assert.isTrue(form.getPayword1().length() >= 6 && form.getPayword2().length() >= 6, "新支付密码长度过短");
			if (!form.getPayword1().equals(form.getPayword2())) {
				throw new RRException("新支付密码两次输入不一致");
			}

			// 设置新支付密码
			member.setPayword(DigestUtils.sha256Hex(form.getPayword1() + member.getSalt()));

		} else {
			throw new RRException("修改失败");
		}

		member.setUpdateTime(new Date());
		memberService.updateById(member);
		return R.ok();
	}

	@Login
	@PostMapping("auth")
	@ApiOperation("实名认证")
	public R auth(@ApiIgnore @LoginUser MemberEntity member, @RequestBody AuthForm form) {
		ValidatorUtils.validateEntity(form);
		Assert.isTrue(member.getAuthStatus() != ProjectConstant.AUTH_STATUS_PASSED, "账号已实名认证");
		Assert.isTrue(memberService.selectCount(new EntityWrapper<MemberEntity>().eq("id_number", form.getIdNumber()).ne("id", member.getId())) == 0, "身份证信息已存在");
		Assert.hasText(member.getFrontImg(), "请上传身份证正面照片");
		Assert.hasText(member.getBackImg(), "请上传身份证反面照片");
		member.setRealname(form.getRealname());
		member.setIdNumber(form.getIdNumber());
		member.setAuthStatus(ProjectConstant.AUTH_STATUS_SUBMIT);
		member.setUpdateTime(new Date());
		memberService.updateById(member);
		return R.ok();
	}

	@Login
	@PostMapping("setPay")
	@ApiOperation("设置收款信息")
	public R setPay(@ApiIgnore @LoginUser MemberEntity member, @RequestBody PayForm form) {
		if (StringUtils.isNotBlank(form.getBankName())) {
			Assert.hasText(form.getBankCardNumber(), "银行卡号不能为空");
			member.setBankName(form.getBankName());
			member.setBankNameBranch(form.getBankNameBranch());
			member.setBankCardNumber(form.getBankCardNumber());
		} else if (StringUtils.isNotBlank(form.getAlipay())) {
			member.setAlipay(form.getAlipay());
		} else if (StringUtils.isNotBlank(form.getWechat())) {
			member.setWechat(form.getWechat());
		} else {
			throw new RRException("设置收款信息失败");
		}
		member.setUpdateTime(new Date());
		memberService.updateAllColumnById(member);
		return R.ok();
	}

	@Login
	@PostMapping("/upload/head")
	@ApiOperation("设置头像")
	public R uploadHead(@RequestParam("file") MultipartFile file) {
		String url = uploadFile(file, ProjectConstant.UPLOAD_TYPE_HEAD);
		memberService.updateImage(getUserId(), ProjectConstant.UPLOAD_TYPE_HEAD, url);
		return R.ok();
	}

	@Login
	@PostMapping("/upload/front")
	@ApiOperation("身份证正面")
	public R uploadFront(@RequestParam("file") MultipartFile file, @ApiIgnore @LoginUser MemberEntity member) {
		Assert.isTrue(member.getAuthStatus() != ProjectConstant.AUTH_STATUS_PASSED, "账号已实名认证");
		String url = uploadFile(file, ProjectConstant.UPLOAD_TYPE_IDFRONT);
		memberService.updateImage(getUserId(), ProjectConstant.UPLOAD_TYPE_IDFRONT, url);
		return R.ok();
	}

	@Login
	@PostMapping("/upload/back")
	@ApiOperation("身份证反面")
	public R uploadBack(@RequestParam("file") MultipartFile file, @ApiIgnore @LoginUser MemberEntity member) {
		Assert.isTrue(member.getAuthStatus() != ProjectConstant.AUTH_STATUS_PASSED, "账号已实名认证");
		String url = uploadFile(file, ProjectConstant.UPLOAD_TYPE_IDBACK);
		memberService.updateImage(getUserId(), ProjectConstant.UPLOAD_TYPE_IDBACK, url);
		return R.ok();
	}

	@Login
	@PostMapping("/upload/alipay")
	@ApiOperation("支付宝收款码")
	public R uploadAlipay(@RequestParam("file") MultipartFile file) {
		String url = uploadFile(file, ProjectConstant.UPLOAD_TYPE_ALIPAY);
		memberService.updateImage(getUserId(), ProjectConstant.UPLOAD_TYPE_ALIPAY, url);
		return R.ok();
	}

	@Login
	@PostMapping("/upload/wechat")
	@ApiOperation("微信收款码")
	public R uploadWechat(@RequestParam("file") MultipartFile file) {
		String url = uploadFile(file, ProjectConstant.UPLOAD_TYPE_WECHAT);
		memberService.updateImage(getUserId(), ProjectConstant.UPLOAD_TYPE_WECHAT, url);
		return R.ok();
	}

	/**
	 * 上传文件
	 * 
	 * @param file
	 * @param type
	 */
	private String uploadFile(MultipartFile file, int type) {
		if (file == null || file.isEmpty()) {
			throw new RRException("上传文件不能为空");
		}
		// 上传文件
		String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
		Assert.isImage(suffix, "请上传图片文件");
		try {
			byte[] bytes = null;
			// 生成文件名
			String fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
			// 文件路径
			String path = DateUtils.format(new Date(), "yyyyMMdd") + "/";
			if (ProjectConstant.UPLOAD_TYPE_HEAD == type) {
				path = "head/" + path;
				// 压缩头像
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				Thumbnails.of(file.getInputStream()).scale(0.25f).outputQuality(0.25f).toOutputStream(bos);
				bytes = bos.toByteArray();
			} else {
				if (ProjectConstant.UPLOAD_TYPE_IDBACK == type || ProjectConstant.UPLOAD_TYPE_IDFRONT == type) {
					path = "auth/" + path;
				} else {
					path = "pay/" + path;
				}
				bytes = file.getBytes();
			}
			String url = OSSFactory.build().upload(bytes, path + fileName);
			// 保存文件信息
			SysOssEntity ossEntity = new SysOssEntity();
			ossEntity.setUrl(url);
			ossEntity.setCreateDate(new Date());
			sysOssService.insert(ossEntity);
			return url;
		} catch (Exception e) {
			logger.error("上传文件失败", e);
			throw new RRException("上传文件失败");
		}
	}
}
